#include "aibase.h"

////////////////////////////////
//
//IMPORTANT! Write the name of your player
//
#define NAMEPLAYER RoadRunner
//
////////////////////////////////

namespace NAMEPLAYER {                  //Do not change this line

  // IMPORTANT! Do not use global variables.

  //////////////////////////////////////////////////
  //
  //   However, it is okay to define const variables, functions,
  // typedefs, or structs/classes. Please do it here:
  //



  //
  //
  //////////////////////////////////////////////////


  //////////////////////////////////////////////////
  //
  //  You must implement the function 'fes_torn'
  //

  struct AIstruct: public AIbase {      //Do not change this line
#include "initializer.h" //Do not change this line

#define DISTANCIA_PELIGRO 100
#define DIRECCIONES 8

    typedef struct {
	int id_rob;
	int dir;
    }dir_rob;

    typedef struct {
	int x;
	int y;
    }Punto;

    vector<dir_rob> *dir_pag;
    vector<dir_rob> *dir_cav;
    
    int cambiaDir(t_robot rob) {
	int dira = 1+random(8);
        if (color(rob.i,rob.j+1) == -1) dira = SUD;
        if (color(rob.i+1,rob.j+1) == -1) dira = SE;
        if (color(rob.i+1,rob.j) == -1) dira = OEST;
        if (color(rob.i+1,rob.j-1) == -1) dira = NO;
        if (color(rob.i,rob.j-1) == -1) dira = NORD;
        if (color(rob.i-1,rob.j-1) == -1) dira = NE;
        if (color(rob.i-1,rob.j) == -1) dira = EST;
        if (color(rob.i-1,rob.j+1) == -1) dira = SO;
	return dira;
    }

    int distancia(Punto& p1,Punto& p2) {
	return ((p2.x - p1.x)*(p2.x - p1.x)) + ((p2.y - p1.y)*(p2.y - p1.y));
	return 0;
    }

    void alrededores(Punto& original, vector<Punto>& vec){
	vec[0].y = vec[1].y = vec[2].y = original.y - 1; 	//NORTE.i-1=NE.i-1=NO.i-1
	vec[0].x = vec[4].x = original.x;			//NORTE.j = SUD.j
	vec[1].x = vec[2].x = vec[3].x = original.x + 1;	//NE.j+1 = EST.j+1 = SE.j+1
	vec[5].x = vec[6].x = vec[7].x = original.x - 1;	//SO.j-1 = OEST.j-1 = NO.j-1
	vec[3].y = vec[4].y = vec[5].y = original.y + 1;        //SE.i+1 = SUD.i+1 = SO.i+1
	vec[6].y = vec[2].y = original.y;			//OEST.i = EST.i
    }

    int direccion(Punto& pos_pag, Punto& pos_siguiente) {
    	int x, y;
	x = pos_siguiente.x - pos_pag.x;
	y = pos_siguiente.y - pos_pag.y;
	if (x == 0 and y == -1) return NORD;
	if (x == 1 and y == -1) return NE;
	if (x == 1 and y == 0) return EST;
	if (x == 1 and y == 1) return SE;
	if (x == 0 and y == 1) return SUD;
	if (x == -1 and y == 1) return SO;
	if (x == -1 and y == 0) return OEST;
	if (x == -1 and y == -1) return NO;
	return 1+random(8);
    }

    void huir(int idpages, Punto& pos_pag) {
	vector<Punto> dir(DIRECCIONES);
	alrededores(pos_pag,dir);
	int n = dir.size();
	for (int i = 0; i < n; ++i) {
		if(distancia(pos_pag, dir[i]) < DISTANCIA_PELIGRO - 1) {
			int dire = direccion(pos_pag, dir[i]);
			dire = cambiaDir(robot(idpages));
			ordena(idpages, dire);
			return;
		}
	}
    }
    
    Punto busca_color(vector<Punto> &dir) {
	Punto pintar;
	pintar.x = -1;
	pintar.y = -1;
	int n = dir.size();
	for (int i = 0; i < n; ++i) {
	    int c = color(dir[i].y,dir[i].x);
	    if (c != -1 and c != 1) {
	      pintar.y = dir[i].y;
	      pintar.x = dir[i].x;
	      return pintar;
	    }
	}
	return pintar;
    }

    void pintar(int idpages, Punto& pos_pag) {
	vector<Punto> dir(DIRECCIONES);
	alrededores(pos_pag,dir);
	Punto pintar;
	pintar = busca_color(dir);
	if (pintar.x == -1 and pintar.y == -1) {
	  int direc = 1 + random(8); //cambiaDir(robot(idpages));
	  //if (direc == -1) direc = SE;
	  ordena(idpages, direc);
	}
	else {
	  ordena(idpages, direccion(pos_pag, pintar));
	}
	 
    }

    bool cavallers_cerca(vector<int>& pag) {
	int num_equips = 4;
	for (int i = 2; i <= num_equips; ++i) {
		vector<int>cav = cavallers(i);
		int n = cav.size();
		int m = pag.size();
		Punto posicion_cav;
		Punto posicion_pag;
		for (int k = 0; k < m; ++k) {
			posicion_pag.y = robot(pag[k]).i;
			posicion_pag.x = robot(pag[k]).j;
			for (int j = 0; j < n; ++j) {
				posicion_cav.y = robot(cav[j]).i;
				posicion_cav.x = robot(cav[j]).j;
				if(distancia(posicion_pag, posicion_cav) < DISTANCIA_PELIGRO) {
					huir(pag[k], posicion_pag);
					return true;
				}
			}
		}
	}
	return false;
    }

    void inicia(vector<int>& origen, vector<dir_rob>& destino) {
	int n = origen.size();
	for (int i = 0; i < n; ++i) {
	  destino[i].id_rob = origen[i];
	  destino[i].dir = 1 + random(8);
	}
    }

    void fes_torn() {
      // Escull una direccio inicial entre EST, SE, i SUD.

     // if (torn_actual()==1) dir = 1 + random(3);
      
    
     // int dir_aux = dir;
      //Pintors: cap a dir
      vector<int> pag = pagesos(1); //1: el meu equip
      vector<int> cav = cavallers(1);
      	

     for (int i = 0; i < (int)pag.size(); ++i) {
        Punto pos_pag;
	pos_pag.x = robot(pag[i]).j;
	pos_pag.y = robot(pag[i]).i;
	if(!cavallers_cerca(pag)) pintar(pag[i],pos_pag);
      }

      for (int i = 0; i < (int)cav.size(); ++i) {
        Punto pos_pag;
	pos_pag.x = robot(cav[i]).j;
	pos_pag.y = robot(cav[i]).i;
	if(!cavallers_cerca(cav)) pintar(cav[i],pos_pag);
      }
      //Soldats: direccio a l'atzar
   //   matar_pagesos(cav);
      
    }

  };

  //
  //
  //////////////////////////////////////////////////  



  AIstruct::Static_Initializer init;    //Do not change this line
};                                      //Do not change this line
